package com.easylinkin.linkappapi.elasticsearch.entity;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.easylinkin.linkappapi.elasticsearch.util.EsCalendar;

import lombok.Data;

/**

/**
 * @Description: 能源环比统计模型
 * @author xuguoqing
 * @version [V1.0, 2020年06月15日]
 * @see  [相关类/方法]
 * @since [产品/模块版本]
 */
@Data
public class MomStatisticModel {
    private  static  final int  MONTHMOM = 2;
    private static final String  CURRENT = "current";
    private static final String  MOM = "mom";
    private static final String  SUMENERGY = "sumEnergy";
    
    
    public  MomStatisticModel (String dataSouceid,String energyKind, Date currentBeginTime, Date currentEndTime ,int   momStatisticKind){
    	this.dataSouceid  = dataSouceid;
    	this.energyKind   = energyKind;
    	this.currentBeginTime =  currentBeginTime;
    	this.currentEndTime = currentEndTime;
    	this.momStatisticKind = momStatisticKind;
    } 
    
	private String  dataSouceid;
	
	private String  energyKind;
	
	//环比统计类型  1 周 2月 3自定义
	private int  momStatisticKind; 
	//当期的起始时间
	private Date currentBeginTime;
	//当期的结束时间
	private Date currentEndTime;
	//当期统计天数
	private int  currentStaticDay;
	//环比时间起始时间
	private Date momBeginTime;
	//环比时间结束时间
	private Date momEndTime;
   //环比统计天数
	private int  momStatisticDay;
	//统计结果集
	Map<String,Map<String,Double>>  staticResultMap = new HashMap<String,Map<String,Double>>();
	//根据查询 参数初始化 
    public  void  initialize() throws ParseException {
    	 Assert.notNull(this.currentBeginTime, "当期的统计时间不能为空");
    	 Assert.notNull(this.currentEndTime ,"当期的结束时间不能为空");
    	 currentBeginTime =EsCalendar.getBeforeDayDateByDate(currentBeginTime, 0);
    	 currentEndTime =EsCalendar.getBeforeDayDateByDate(currentEndTime, 0);
        //通过当期的时间和环比类型统计上期的时间
    	 if(momStatisticKind == MONTHMOM)
    	 {
    		 currentStaticDay = EsCalendar.getDiffDay(currentBeginTime, currentEndTime)+1;
    		 
    		 momBeginTime = EsCalendar.getBefreMonthfirstDayByDate(currentBeginTime, 1);
    		 
    		 momEndTime = EsCalendar.getBefreMonthLastDayByDate(currentBeginTime, 1);
    		 
    		 momStatisticDay  = EsCalendar.getMonthDayByDate(momBeginTime);
    		 
    	 }else{
    		
    		 currentStaticDay = EsCalendar.getDiffDay(currentBeginTime, currentEndTime)+1;
    		 
    		 momEndTime = EsCalendar.getBeforeDayDateByDate(currentBeginTime, 1);
    		 
    		 momBeginTime = EsCalendar.getBeforeDayDateByDate(currentBeginTime, currentStaticDay);
    		 
    		 momStatisticDay  = currentStaticDay;
    	 }
    }
	
   
    //es 查询结果为一个HashMap<String YYYYMMDD,Double> 即数据源某天的能源量  
    public  void  constructStaticSequenMap(List<DateSourceEnergyRecord> dayEnergylist, int switchPageType) {
    	Map<String,List<DateSourceEnergyRecord>>staticSequenMap =dayEnergylist.stream().collect(Collectors.groupingBy(DateSourceEnergyRecord::haveStaticTime));
    	//的到分组结果 当期的分组，上期的分组
    	//当期的分组,并处理
    	Double  cueerntSumEnergy = 0d;
    	Double  momtSumEnergy = 0d;
    	Map<String, DoubleSummaryStatistics> currentdayMap; 
    	Map<String, Double> currentdayFinallMap = null;
    	Map<String, DoubleSummaryStatistics> momdayMap;
    	Map<String, Double> momdayFinallMap = null;
    	Map<String, Double> sumEnergyMap = new HashMap<String, Double>();
    	List<DateSourceEnergyRecord>  currentStaRecordList = staticSequenMap.get(CURRENT);
    	List<DateSourceEnergyRecord>  momStaRecordList = staticSequenMap.get(MOM);

		if (2 == switchPageType) {//客流页签数据统计
			if(!ObjectUtils.isEmpty(currentStaRecordList)) {
				cueerntSumEnergy = currentStaRecordList.stream().mapToDouble(DateSourceEnergyRecord::getOnDutyPeopleNum).sum();
				cueerntSumEnergy = ((double) Math.round(cueerntSumEnergy * 100)) / 100;
				currentdayMap = currentStaRecordList.stream().collect(Collectors.groupingBy(DateSourceEnergyRecord::haveDayTime, Collectors.summarizingDouble(DateSourceEnergyRecord::getOnDutyPeopleNum)));
				currentdayFinallMap =getDayCollect(currentdayMap,this.currentBeginTime,this.currentStaticDay);
			}else{
				currentdayMap = new HashMap<String, DoubleSummaryStatistics>();
			}
			currentdayFinallMap =getDayCollect(currentdayMap,this.currentBeginTime,this.currentStaticDay);
			if(!ObjectUtils.isEmpty(momStaRecordList)){
				momtSumEnergy= momStaRecordList.stream().mapToDouble(DateSourceEnergyRecord::getOnDutyPeopleNum).sum();
				momtSumEnergy = ((double)Math.round(momtSumEnergy*100))/100;
				momdayMap = momStaRecordList.stream().collect(Collectors.groupingBy(DateSourceEnergyRecord::haveDayTime, Collectors.summarizingDouble(DateSourceEnergyRecord::getOnDutyPeopleNum)));
			} else {
				momdayMap = new HashMap<String, DoubleSummaryStatistics>();
			}
			momdayFinallMap =getDayCollect(momdayMap,this.momBeginTime,this.momStatisticDay);
		}else {
			if(!ObjectUtils.isEmpty(currentStaRecordList)){
				cueerntSumEnergy = currentStaRecordList.stream().mapToDouble(DateSourceEnergyRecord::getDayEnergy).sum();
				cueerntSumEnergy =((double)Math.round(cueerntSumEnergy*100))/100;
				currentdayMap = currentStaRecordList.stream().collect(Collectors.groupingBy(DateSourceEnergyRecord::haveDayTime, Collectors.summarizingDouble(DateSourceEnergyRecord::getDayEnergy)));
    			currentdayFinallMap =getDayCollect(currentdayMap,this.currentBeginTime,this.currentStaticDay);
			}else{
				currentdayMap = new HashMap<String, DoubleSummaryStatistics>();
			}
    		currentdayFinallMap =getDayCollect(currentdayMap,this.currentBeginTime,this.currentStaticDay);
    	
			if(!ObjectUtils.isEmpty(momStaRecordList)){
				momtSumEnergy= momStaRecordList.stream().mapToDouble(DateSourceEnergyRecord::getDayEnergy).sum();
				momtSumEnergy = ((double)Math.round(momtSumEnergy*100))/100;
				momdayMap = momStaRecordList.stream().collect(Collectors.groupingBy(DateSourceEnergyRecord::haveDayTime, Collectors.summarizingDouble(DateSourceEnergyRecord::getDayEnergy)));
			} else {
				momdayMap = new HashMap<String, DoubleSummaryStatistics>();
			}
			momdayFinallMap =getDayCollect(momdayMap,this.momBeginTime,this.momStatisticDay);
		}
		sumEnergyMap.put(CURRENT, cueerntSumEnergy);
		sumEnergyMap.put(MOM, momtSumEnergy);
		staticResultMap.put(SUMENERGY, sumEnergyMap);
		staticResultMap.put(CURRENT, currentdayFinallMap);
		staticResultMap.put(MOM, momdayFinallMap);
   }


	public  void  constructStaticSequenResult(List<EsEtlStatisticModel> dayEnergylist) {
		Map<String,List<EsEtlStatisticModel>> staticSequenMap = new HashMap<>();
		staticSequenMap = this.getEsEtlStatisticModelMap(dayEnergylist);

		//的到分组结果 当期的分组，上期的分组
		//当期的分组,并处理
		Double  cueerntSumEnergy = 0d;
		Double  momtSumEnergy = 0d;
		Map<String, DoubleSummaryStatistics> currentdayMap;
		Map<String, Double> currentdayFinallMap = null;
		Map<String, DoubleSummaryStatistics> momdayMap;
		Map<String, Double> momdayFinallMap = null;
		Map<String, Double> sumEnergyMap = new HashMap<String, Double>();
		List<EsEtlStatisticModel>  currentStaRecordList = staticSequenMap.get(CURRENT);
		List<EsEtlStatisticModel>  momStaRecordList = staticSequenMap.get(MOM);

		if(!ObjectUtils.isEmpty(currentStaRecordList)){
			cueerntSumEnergy = currentStaRecordList.stream().mapToDouble(EsEtlStatisticModel::getEtlValue).sum();
			cueerntSumEnergy =((double)Math.round(cueerntSumEnergy*100))/100;
			currentdayMap = currentStaRecordList.stream().collect(Collectors.groupingBy(EsEtlStatisticModel::getCalcDate, Collectors.summarizingDouble(EsEtlStatisticModel::getEtlValue)));
			currentdayFinallMap =getDayCollect(currentdayMap,this.currentBeginTime,this.currentStaticDay);
		}else{
			currentdayMap = new HashMap<String, DoubleSummaryStatistics>();
		}
		currentdayFinallMap =getDayCollect(currentdayMap,this.currentBeginTime,this.currentStaticDay);

		if(!ObjectUtils.isEmpty(momStaRecordList)){
			momtSumEnergy= momStaRecordList.stream().mapToDouble(EsEtlStatisticModel::getEtlValue).sum();
			momtSumEnergy = ((double)Math.round(momtSumEnergy*100))/100;
			momdayMap = momStaRecordList.stream().collect(Collectors.groupingBy(EsEtlStatisticModel::getCalcDate, Collectors.summarizingDouble(EsEtlStatisticModel::getEtlValue)));
		} else {
			momdayMap = new HashMap<String, DoubleSummaryStatistics>();
		}
		momdayFinallMap =getDayCollect(momdayMap,this.momBeginTime,this.momStatisticDay);

		sumEnergyMap.put(CURRENT, cueerntSumEnergy);
		sumEnergyMap.put(MOM, momtSumEnergy);
		staticResultMap.put(SUMENERGY, sumEnergyMap);
		staticResultMap.put(CURRENT, currentdayFinallMap);
		staticResultMap.put(MOM, momdayFinallMap);
	}
	
    
	private Map<String, Double> getDayCollect(Map<String, DoubleSummaryStatistics>  dayMap,Date beginDate,int dayCount) {
	        String day;
	        Map<String, Double> map = new LinkedHashMap<>();
	        double  daySum;
	        for (int i =0; i <dayCount; i++) {
	            day = EsCalendar.getBeforeDayByDate(beginDate, -i);
	            DoubleSummaryStatistics sunObj = dayMap.get(day);
	            if (sunObj != null) {
	            	daySum = (double)Math.round(sunObj.getSum()*100)/100;
	                map.put(day,daySum);
	            } else {
	                map.put(day, Double.valueOf(0));
	            }
	        }
	        return map;
    }

	/**
	 * 时间段分类
	 */
	public  Map<String,List<EsEtlStatisticModel>>  getEsEtlStatisticModelMap(List<EsEtlStatisticModel> dayEnergylist){
		Map<String,List<EsEtlStatisticModel>> map = new HashMap<>();
		List<EsEtlStatisticModel> currList = new ArrayList<>();
		List<EsEtlStatisticModel> momList = new ArrayList<>();
		for (EsEtlStatisticModel esEtlStatisticModel : dayEnergylist) {
			if(!esEtlStatisticModel.getDateTime().before(this.getCurrentBeginTime())&&!esEtlStatisticModel.getDateTime().after(this.getCurrentEndTime()))
			{
				currList.add(esEtlStatisticModel);
			}else if(!esEtlStatisticModel.getDateTime().before(this.getMomBeginTime())&&!esEtlStatisticModel.getDateTime().after(this.getMomEndTime()))
			{
				momList.add(esEtlStatisticModel);

			}
		}
		map.put(CURRENT, currList);
		map.put(MOM, momList);
		return map;
	}
}

